package com.dkakunsi.monev.entity;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Table(name="KEGIATAN")
public class Kegiatan implements MonevNameableEntity {
	private int id;
	private String nama;
	private Program program;
	private Kegiatan parent;
	private String instansiTerkait;
	private int tahunAnggaran;
	private String sumberAnggaran;
	private long anggaran;
	private String lokasi;
	private String fotoLokasi;
	private Progress progres;
	private List<Kegiatan> subKegiatan;
	private List<Realisasi> listRealisasi;
	private List<Indikator> listIndikator;
	private List<RealisasiDana> listRealisasiDana;
	private boolean root;
	
	public Kegiatan() {
		initProgres();
		setRoot(true);
	}

	public Kegiatan(Program program, String nama) {
		initProgres();
		setRoot(true);
		this.setProgram(program);
		this.setNama(nama);
	}

	public Kegiatan(Program program, Kegiatan parent, String nama) {
		initProgres();
		setRoot(true);
		this.setProgram(program);
		this.setParent(parent);
		this.setNama(nama);
	}

	public Kegiatan(Program program, String nama, int tahunAnggaran, String lokasi,
			String instansiTerkait, long anggaran, String sumberAnggaran) {
		initProgres();
		setRoot(true);
		this.setProgram(program);
		this.setNama(nama);
		this.setTahunAnggaran(tahunAnggaran);
		this.setLokasi(lokasi);
		this.setInstansiTerkait(instansiTerkait);
		this.setAnggaran(anggaran);
		this.setSumberAnggaran(sumberAnggaran);
	}

	public Kegiatan(Program program, Kegiatan parent, String nama, int tahunAnggaran, String lokasi,
			String instansiTerkait, long anggaran, String sumberAnggaran) {
		initProgres();
		setRoot(true);
		this.setProgram(program);
		this.setParent(parent);
		this.setNama(nama);
		this.setTahunAnggaran(tahunAnggaran);
		this.setLokasi(lokasi);
		this.setInstansiTerkait(instansiTerkait);
		this.setAnggaran(anggaran);
		this.setSumberAnggaran(sumberAnggaran);
	}
	
	private void initProgres() {
		progres = new Progress(0, 0);
	}

	@Id @GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name="id", length=11, nullable=false)
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	@Column(name="nama", length=255, nullable=false)
	public String getNama() {
		return nama;
	}

	public void setNama(String nama) {
		this.nama = nama;
	}

	@Column(name="tahun_anggaran", nullable=true)
	public int getTahunAnggaran() {
		return tahunAnggaran;
	}

	public void setTahunAnggaran(int tahunAnggaran) {
		this.tahunAnggaran = tahunAnggaran;
	}

	@Column(name="lokasi", length=255, nullable=true)
	public String getLokasi() {
		return lokasi;
	}

	public void setLokasi(String lokasi) {
		this.lokasi = lokasi;
	}

	@Column(name="foto_lokasi", length=255, nullable=true)
	public String getFotoLokasi() {
		return fotoLokasi;
	}

	public void setFotoLokasi(String fotoLokasi) {
		this.fotoLokasi = fotoLokasi;
	}

	@Column(name="instansi_terkait", length=255, nullable=true)
	public String getInstansiTerkait() {
		return instansiTerkait;
	}

	public void setInstansiTerkait(String instansiTerkait) {
		this.instansiTerkait = instansiTerkait;
	}

	@Column(name="anggaran", nullable=true)
	public long getAnggaran() {
		return anggaran;
	}

	public void setAnggaran(long anggaran) {
		this.anggaran = anggaran;
	}

	@Column(name="sumber_anggaran", length=255, nullable=true)
	public String getSumberAnggaran() {
		return sumberAnggaran;
	}

	public void setSumberAnggaran(String sumberAnggaran) {
		this.sumberAnggaran = sumberAnggaran;
	}

	@ManyToOne(fetch=FetchType.EAGER)
	@JoinColumn(name="program", nullable=false)
	public Program getProgram() {
		return program;
	}

	public void setProgram(Program program) {
		this.program = program;
	}

	@ManyToOne(fetch=FetchType.EAGER)
	@JoinColumn(name="parent", nullable=true)
	public Kegiatan getParent() {
		return parent;
	}

	public void setParent(Kegiatan parent) {
		this.parent = parent;
		setRoot(false);
	}

	@Embedded
	public Progress getProgres() {
		return progres;
	}

	public void setProgres(Progress monitoring) {
		this.progres = monitoring;
	}

	@OneToMany(mappedBy="parent", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
	public List<Kegiatan> getSubKegiatan() {
		return subKegiatan;
	}

	public void setSubKegiatan(List<Kegiatan> subKegiatan) {
		this.subKegiatan = subKegiatan;
	}

	@OneToMany(mappedBy="kegiatan", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
	public List<Realisasi> getListRealisasi() {
		return listRealisasi;
	}

	public void setListRealisasi(List<Realisasi> listRealisasiDana) {
		this.listRealisasi = listRealisasiDana;
	}

	@OneToMany(mappedBy="kegiatan", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
	public List<Indikator> getListIndikator() {
		return listIndikator;
	}

	public void setListIndikator(List<Indikator> listIndikator) {
		this.listIndikator = listIndikator;
	}

	@OneToMany(mappedBy="kegiatan", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
	public List<RealisasiDana> getListRealisasiDana() {
		return listRealisasiDana;
	}
	
	public void setListRealisasiDana(List<RealisasiDana> listRealisasiDana) {
		this.listRealisasiDana = listRealisasiDana;
	}
	
	public Realisasi getRealisasi(int bulan) {
		for(Realisasi r : listRealisasi) {
			if(r.getBulan() == bulan)
				return r;
		}
		return null;
	}
	
	public double presentaseRealisasiDana() {
		return (progres.getProgresDana() / anggaran) * 100;
	}
	
	public double presentaseRealisasiFisik() {
		return progres.getProgresFisik();
	}
	
	@Transient
	public boolean isRoot() {
		return root;
	}
	
	public void setRoot(boolean b) {
		root = b;
	}
	
	public void copyValue(Kegiatan k) {
		this.setNama(k.getNama());
		this.setProgram(k.getProgram());
		this.setParent(k.getParent());
		this.setInstansiTerkait(k.getInstansiTerkait());
		this.setTahunAnggaran(k.getTahunAnggaran());
		this.setSumberAnggaran(k.getSumberAnggaran());
		this.setAnggaran(k.getAnggaran());
		this.setLokasi(k.getLokasi());
		this.setFotoLokasi(k.getFotoLokasi());
		this.setProgres(k.getProgres());
	}
}
